/**
 * 组件事件总线系统
 * 解决组件间强耦合问题，建立松耦合的事件驱动架构
 */

import { ServiceLogger } from '../logging/UnifiedLogger';
import { GameError, ErrorFactory } from '../error/ErrorTypes';

/**
 * 事件优先级枚举
 */
export enum EventPriority {
    LOWEST = 0,
    LOW = 25,
    NORMAL = 50,
    HIGH = 75,
    HIGHEST = 100
}

/**
 * 事件接口
 */
export interface ComponentEvent {
    /** 事件类型 */
    type: string;
    /** 事件源组件 */
    source: string;
    /** 事件数据 */
    data: any;
    /** 时间戳 */
    timestamp: number;
    /** 事件ID */
    eventId: string;
    /** 是否可以取消 */
    cancelable?: boolean;
    /** 是否已取消 */
    cancelled?: boolean;
}

/**
 * 事件监听器接口
 */
export interface EventListener {
    /** 监听器ID */
    id: string;
    /** 事件类型 */
    eventType: string;
    /** 监听器组件 */
    component: string;
    /** 处理函数 */
    handler: (event: ComponentEvent) => Promise<void> | void;
    /** 优先级 */
    priority: EventPriority;
    /** 是否只执行一次 */
    once?: boolean;
    /** 是否异步 */
    async?: boolean;
}

/**
 * 事件统计信息
 */
interface EventMetrics {
    totalEvents: number;
    eventsByType: Map<string, number>;
    lastEventTime: number;
    avgProcessingTime: number;
    errorCount: number;
}

/**
 * 组件事件总线
 */
export class ComponentEventBus {
    private static instance: ComponentEventBus;
    private listeners = new Map<string, EventListener[]>();
    private eventHistory: ComponentEvent[] = [];
    private metrics: EventMetrics;
    private logger: ServiceLogger;
    private maxHistorySize = 1000;
    private isEnabled = true;

    private constructor() {
        this.logger = new ServiceLogger('ComponentEventBus');
        this.metrics = {
            totalEvents: 0,
            eventsByType: new Map(),
            lastEventTime: 0,
            avgProcessingTime: 0,
            errorCount: 0
        };
    }

    /**
     * 获取单例实例
     */
    static getInstance(): ComponentEventBus {
        if (!this.instance) {
            this.instance = new ComponentEventBus();
        }
        return this.instance;
    }

    /**
     * 注册事件监听器
     */
    on(
        eventType: string, 
        component: string, 
        handler: (event: ComponentEvent) => Promise<void> | void,
        options: {
            priority?: EventPriority;
            once?: boolean;
            async?: boolean;
        } = {}
    ): string {
        const listenerId = `${component}_${eventType}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
        
        const listener: EventListener = {
            id: listenerId,
            eventType,
            component,
            handler,
            priority: options.priority || EventPriority.NORMAL,
            once: options.once || false,
            async: options.async !== false // 默认异步
        };

        if (!this.listeners.has(eventType)) {
            this.listeners.set(eventType, []);
        }

        const typeListeners = this.listeners.get(eventType)!;
        typeListeners.push(listener);
        
        // 按优先级排序
        typeListeners.sort((a, b) => b.priority - a.priority);

        this.logger.debug(`Event listener registered: ${component} -> ${eventType}`, {
            metadata: { listenerId, priority: listener.priority, once: listener.once }
        });

        return listenerId;
    }

    /**
     * 注册一次性事件监听器
     */
    once(
        eventType: string,
        component: string,
        handler: (event: ComponentEvent) => Promise<void> | void,
        priority: EventPriority = EventPriority.NORMAL
    ): string {
        return this.on(eventType, component, handler, { priority, once: true });
    }

    /**
     * 移除事件监听器
     */
    off(listenerId: string): boolean {
        for (const [eventType, listeners] of this.listeners.entries()) {
            const index = listeners.findIndex(l => l.id === listenerId);
            if (index >= 0) {
                const listener = listeners.splice(index, 1)[0];
                this.logger.debug(`Event listener removed: ${listener.component} -> ${eventType}`);
                return true;
            }
        }
        return false;
    }

    /**
     * 移除组件的所有监听器
     */
    offByComponent(component: string): number {
        let removedCount = 0;
        
        for (const [eventType, listeners] of this.listeners.entries()) {
            const initialLength = listeners.length;
            this.listeners.set(eventType, listeners.filter(l => l.component !== component));
            removedCount += initialLength - this.listeners.get(eventType)!.length;
        }

        if (removedCount > 0) {
            this.logger.debug(`Removed ${removedCount} listeners for component: ${component}`);
        }

        return removedCount;
    }

    /**
     * 发射事件
     */
    async emit(
        eventType: string,
        source: string,
        data: any,
        options: {
            cancelable?: boolean;
            timeout?: number;
        } = {}
    ): Promise<ComponentEvent> {
        if (!this.isEnabled) {
            this.logger.debug('Event bus is disabled, skipping event emission');
            return this.createEvent(eventType, source, data, options.cancelable);
        }

        const startTime = Date.now();
        const event = this.createEvent(eventType, source, data, options.cancelable);

        try {
            this.logger.debug(`Emitting event: ${eventType}`, {
                metadata: { source, eventId: event.eventId, dataKeys: Object.keys(data || {}) }
            });

            // 更新统计
            this.updateMetrics(eventType, startTime);

            // 获取监听器
            const listeners = this.listeners.get(eventType) || [];
            
            if (listeners.length === 0) {
                this.logger.debug(`No listeners for event type: ${eventType}`);
                return event;
            }

            // 执行监听器
            await this.executeListeners(event, listeners, options.timeout);

            // 记录到历史
            this.addToHistory(event);

            const processingTime = Date.now() - startTime;
            this.logger.debug(`Event processed successfully: ${eventType}`, {
                metadata: { 
                    eventId: event.eventId, 
                    listenersCount: listeners.length,
                    processingTime,
                    cancelled: event.cancelled
                }
            });

            return event;

        } catch (error) {
            this.metrics.errorCount++;
            const gameError = ErrorFactory.serviceUnavailable('ComponentEventBus', {
                metadata: { eventType, source, eventId: event.eventId }
            });
            
            this.logger.error(`Event processing failed: ${eventType}`, { 
                metadata: { eventId: event.eventId } 
            }, gameError);
            
            throw gameError;
        }
    }

    /**
     * 同步发射事件（阻塞）
     */
    emitSync(eventType: string, source: string, data: any): ComponentEvent {
        const event = this.createEvent(eventType, source, data);
        const listeners = this.listeners.get(eventType) || [];

        this.logger.debug(`Emitting sync event: ${eventType}`, {
            metadata: { source, listenersCount: listeners.length }
        });

        for (const listener of listeners) {
            try {
                const result = listener.handler(event);
                
                // 如果返回Promise但我们在同步模式，警告
                if (result instanceof Promise) {
                    this.logger.warn(`Async handler in sync event: ${eventType}`, {
                        metadata: { component: listener.component }
                    });
                }

                if (event.cancelled) {
                    break;
                }
            } catch (error) {
                this.logger.error(`Sync listener failed: ${listener.component}`, error);
            }
        }

        this.addToHistory(event);
        return event;
    }

    /**
     * 创建事件对象
     */
    private createEvent(eventType: string, source: string, data: any, cancelable = false): ComponentEvent {
        return {
            type: eventType,
            source,
            data,
            timestamp: Date.now(),
            eventId: `${eventType}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
            cancelable,
            cancelled: false
        };
    }

    /**
     * 执行监听器
     */
    private async executeListeners(
        event: ComponentEvent, 
        listeners: EventListener[], 
        timeout?: number
    ): Promise<void> {
        const executePromises: Promise<void>[] = [];
        const onceListeners: string[] = [];

        for (const listener of listeners) {
            try {
                // 检查是否应该执行
                if (event.cancelled && event.cancelable) {
                    this.logger.debug(`Event cancelled, skipping listener: ${listener.component}`);
                    continue;
                }

                // 执行监听器
                const executePromise = this.executeListener(listener, event, timeout);
                
                if (listener.async) {
                    executePromises.push(executePromise);
                } else {
                    await executePromise;
                }

                // 记录一次性监听器
                if (listener.once) {
                    onceListeners.push(listener.id);
                }

            } catch (error) {
                this.logger.error(`Listener execution failed: ${listener.component}`, error, {
                    metadata: { eventType: event.type, eventId: event.eventId }
                });
            }
        }

        // 等待异步监听器完成
        if (executePromises.length > 0) {
            await Promise.allSettled(executePromises);
        }

        // 移除一次性监听器
        onceListeners.forEach(id => this.off(id));
    }

    /**
     * 执行单个监听器
     */
    private async executeListener(
        listener: EventListener, 
        event: ComponentEvent, 
        timeout?: number
    ): Promise<void> {
        const listenerStart = Date.now();
        
        try {
            let handlerPromise = Promise.resolve(listener.handler(event));
            
            // 应用超时
            if (timeout && timeout > 0) {
                handlerPromise = Promise.race([
                    handlerPromise,
                    new Promise<void>((_, reject) => 
                        setTimeout(() => reject(new Error(`Listener timeout: ${timeout}ms`)), timeout)
                    )
                ]);
            }

            await handlerPromise;

            const duration = Date.now() - listenerStart;
            if (duration > 1000) { // 超过1秒的慢监听器
                this.logger.warn(`Slow listener detected: ${listener.component}`, {
                    metadata: { eventType: event.type, duration }
                });
            }

        } catch (error) {
            this.logger.error(`Listener handler failed: ${listener.component}`, error, {
                metadata: { eventType: event.type, eventId: event.eventId }
            });
            throw error;
        }
    }

    /**
     * 更新统计信息
     */
    private updateMetrics(eventType: string, startTime: number): void {
        this.metrics.totalEvents++;
        this.metrics.lastEventTime = startTime;
        
        const typeCount = this.metrics.eventsByType.get(eventType) || 0;
        this.metrics.eventsByType.set(eventType, typeCount + 1);
    }

    /**
     * 添加到历史记录
     */
    private addToHistory(event: ComponentEvent): void {
        this.eventHistory.push(event);
        
        // 保持历史记录大小
        if (this.eventHistory.length > this.maxHistorySize) {
            this.eventHistory.shift();
        }
    }

    /**
     * 获取事件统计
     */
    getMetrics(): EventMetrics {
        const processingTimes = this.eventHistory
            .filter(e => e.timestamp > Date.now() - 60000) // 最近1分钟
            .map(e => 10); // 简化处理时间计算

        this.metrics.avgProcessingTime = processingTimes.length > 0 
            ? processingTimes.reduce((a, b) => a + b, 0) / processingTimes.length 
            : 0;

        return { ...this.metrics };
    }

    /**
     * 获取事件历史
     */
    getEventHistory(limit = 100): ComponentEvent[] {
        return this.eventHistory.slice(-limit);
    }

    /**
     * 获取监听器信息
     */
    getListeners(): Map<string, EventListener[]> {
        return new Map(this.listeners);
    }

    /**
     * 清理过期历史
     */
    cleanup(): void {
        const cutoff = Date.now() - 24 * 60 * 60 * 1000; // 24小时前
        this.eventHistory = this.eventHistory.filter(e => e.timestamp > cutoff);
        
        this.logger.debug('Event history cleaned up', {
            metadata: { remainingEvents: this.eventHistory.length }
        });
    }

    /**
     * 启用/禁用事件总线
     */
    setEnabled(enabled: boolean): void {
        this.isEnabled = enabled;
        this.logger.info(`Event bus ${enabled ? 'enabled' : 'disabled'}`);
    }

    /**
     * 重置统计信息
     */
    resetMetrics(): void {
        this.metrics = {
            totalEvents: 0,
            eventsByType: new Map(),
            lastEventTime: 0,
            avgProcessingTime: 0,
            errorCount: 0
        };
        this.eventHistory = [];
        this.logger.info('Event bus metrics reset');
    }
}

/**
 * 全局事件总线实例
 */
export const componentEventBus = ComponentEventBus.getInstance();
